package pe.gob.foncodes.ssa.bs.seguridad.domain;

import java.io.Serializable;
import java.math.BigInteger;
import java.util.Date;
import java.util.List;
import javax.persistence.Basic;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;
import javax.validation.constraints.NotNull;
import pe.gob.foncodes.ssa.bs.common.domain.EntidadBase;
import pe.gob.foncodes.ssa.bs.common.util.Constante;

/**
 *
 * @author Gcarlos
 */

@Entity
@Table(name = "OPCION", catalog = "", schema = "SSA")
@NamedQueries({
    @NamedQuery(name = "Opcion.findAll", query = "SELECT o FROM Opcion o"),
    
    @NamedQuery(name = "Opcion.findByFlgActivo", query = "SELECT o FROM Opcion o WHERE o.flgActivo = :flgActivo"),
    
    @NamedQuery(name = "Opcion.findByTxtOpcion", query = "SELECT o FROM Opcion o WHERE UPPER(o.txtOpcion) LIKE ?1 AND o.nidModulo.id = ?2 ORDER BY o.id"),
    
    @NamedQuery(name = "Opcion.findByTxtOpcionAndFlgActivo", query = "SELECT o FROM Opcion o WHERE UPPER(o.txtOpcion) LIKE ?1 AND o.flgActivo = ?2 AND o.nidModulo.id = ?3 ORDER BY o.numOrden"),
    
    @NamedQuery(name = "Opcion.findByNidModulo", query = "SELECT o FROM Opcion o WHERE o.flgActivo = ?1 AND o.nidModulo.id = ?2 ORDER BY o.numOrden"),
    
    @NamedQuery(name = "Opcion.findOnlyNidOpcionPadre", query = "SELECT o FROM Opcion o WHERE o.nidOpcionPadre IS NULL AND o.nidModulo.id = ?1 ORDER BY o.numOrden"),
    
    @NamedQuery(name = "Opcion.findByNidOpcionPadre", query = "SELECT o FROM Opcion o JOIN o.nidOpcionPadre op JOIN o.nidModulo m WHERE op.id = ?1 AND m.id = ?2 ORDER BY o.numOrden"),
    
    @NamedQuery(name = "Opcion.findOnlyNidOpcionPadreAndFlgActivo", query = "SELECT o FROM Opcion o WHERE o.nidOpcionPadre IS NULL AND o.nidModulo.id = ?1 AND o.flgActivo = ?2 ORDER BY o.numOrden"),
    
    @NamedQuery(name = "Opcion.findByNidOpcionPadreAndFlgActivo", query = "SELECT o FROM Opcion o JOIN o.nidOpcionPadre op JOIN o.nidModulo m WHERE op.id = ?1 AND m.id = ?2 AND o.flgActivo = ?3 ORDER BY o.numOrden"),
    
    @NamedQuery(name = "Opcion.findByNidOpcionAndNidOpcionPadreAndFlgActivo", query = "SELECT o FROM Opcion o JOIN o.nidModulo m WHERE m.id = ?1 AND (o.id = ?2 OR o.nidOpcionPadre.id = ?2) AND o.flgActivo = ?3 ORDER BY o.numOrden"),
    
    @NamedQuery(name = "Opcion.findByReportePorModulo", query = "SELECT m.txtModulo, '', o.txtOpcion, op.txtOpcion, o.flgActivo, o.numOrden"
                                                        + " FROM Opcion o"
                                                        + " LEFT JOIN o.nidOpcionPadre op"
                                                        + " INNER JOIN o.nidModulo m"
                                                        + " WHERE (m.id = ?1 OR ?1 IS NULL)"
                                                        + " AND (o.flgActivo = ?2 OR ?2 IS NULL)"
                                                        + " ORDER BY m.txtModulo, o.flgActivo DESC, CASE WHEN op.txtOpcion IS NULL THEN 0 ELSE 1 END, op.numOrden, o.numOrden"),
    
    @NamedQuery(name = "Opcion.findByReportePorPerfil", query = "SELECT m.txtModulo, p.txtPerfil, o.txtOpcion, op.txtOpcion, o.flgActivo, o.numOrden"
                                                        + " FROM Opcion o"
                                                        + " LEFT JOIN o.nidOpcionPadre op"
                                                        + " INNER JOIN o.nidModulo m"
                                                        + " INNER JOIN o.perfilOpcionList po"
                                                        + " INNER JOIN po.perfil p"
                                                        + " WHERE (m.id = ?1 OR ?1 IS NULL)"
                                                        + " AND (p.id = ?2 OR ?2 IS NULL)"
                                                        + " AND (o.flgActivo = ?3 OR ?3 IS NULL)"
                                                        + " ORDER BY m.txtModulo, o.flgActivo DESC, p.txtPerfil, CASE WHEN op.txtOpcion IS NULL THEN 0 ELSE 1 END, op.numOrden, o.numOrden"),    
    @NamedQuery(name = "Opcion.findFirstLevelNodes", query = "SELECT DISTINCT mo.id, mo.txtModulo, mop.id, mop.txtModulo, o.id, o.txtOpcion, "
                                                        + " o.nidOpcionPadre.id, o.numOrden, a.id, a.txtAccion, a.txtNombreObjeto, a.txtUrl, "
                                                        + " a.flgDefault, ua.flgConsulta, o.txtNombreObjeto, o.flgVisible, up.flgConsulta FROM Usuario u"
                                                        + " JOIN u.usuarioPerfilList up"
                                                        + " JOIN up.usuarioAutorizacionList ua"
                                                        + " JOIN ua.accion a"
                                                        + " JOIN a.nidOpcion o"
                                                        + " JOIN o.nidModulo mo"
                                                        + " LEFT JOIN mo.nidModuloPadre mop"
                                                        + " WHERE ua.flgActivo = '"+Constante.ESTADO_ACTIVO+"'"
                                                        + " AND a.flgActivo = '"+Constante.ESTADO_ACTIVO+"'"
                                                        + " AND o.flgActivo = '"+Constante.ESTADO_ACTIVO+"'"
                                                        + " AND o.nidOpcionPadre IS NULL AND a.flgDefault = '1'"
                                                        + " AND u.id = ?1 AND up.flgActivo = '"+Constante.ESTADO_ACTIVO+"'"
                                                        + " AND mo.id IN ( ?2 ) "
                                                        + " AND up.codZonal = ?3"
                                                        + " ORDER BY o.numOrden ASC"),
    @NamedQuery(name = "Opcion.findOtherLevelNodes", query = "SELECT DISTINCT o.id, o.txtOpcion, op.id, o.numOrden,"
                                                        + " a.id, a.txtAccion, a.txtNombreObjeto, a.txtUrl, a.flgDefault, ua.flgConsulta, "
                                                        + " o.txtNombreObjeto, o.flgVisible FROM Usuario u"
                                                        + " JOIN u.usuarioPerfilList up"
                                                        + " JOIN up.usuarioAutorizacionList ua"
                                                        + " JOIN ua.accion a"
                                                        + " JOIN a.nidOpcion o"
                                                        + " JOIN o.nidOpcionPadre op"
                                                        + " WHERE ua.flgActivo ='" + Constante.ESTADO_ACTIVO + "'"
                                                        + " AND a.flgActivo = '" + Constante.ESTADO_ACTIVO + "'"
                                                        + " AND o.flgActivo = '" + Constante.ESTADO_ACTIVO + "'"
                                                        + " AND op.id = ?1 AND a.flgDefault='1' "
                                                        + " AND u.id= ?2 AND up.flgActivo = '"+Constante.ESTADO_ACTIVO+"'"
                                                        + " AND up.codZonal = ?3"
                                                        + " ORDER BY a.id ASC")
})
public class Opcion extends EntidadBase implements Serializable {

    private static final long serialVersionUID = 1L;
    private String txtOpcion;
    private String flgActivo;
    private Date fecCaducidad;
    private BigInteger numOrden;
    private String txtUrl;
    private String txtObservacion;
    private List<PerfilOpcion> perfilOpcionList;
    private List<Accion> accionList;
    private List<Opcion> opcionList;
    private Opcion nidOpcionPadre;
    private Modulo nidModulo;
    private String txtNombreObjeto;;
    private String flgVisible;
    
    private String ruta;
    private boolean BflgActivo;
    private boolean BflgConsulta;
    
    public Opcion() {
    }

    @Id
    @Basic(optional = false)
    @NotNull
    @SequenceGenerator(schema="SSA", name="SQ_OPCION",sequenceName="SSA.SQ_OPCION", allocationSize=1)
    @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="SQ_OPCION")
    @Column(name = "NID_OPCION", nullable = false, precision = 0, scale = -127)
    @Override
    public Long getId() {
        return super.getId();
    }

    @Column(name = "NID_CONTROL_ACCESO_WEB", precision = 0, scale = -127)
    @Override
    public Long getNIdCtrlAccesoWeb() {
        return super.getNIdCtrlAccesoWeb();
    }
    
    @Column(name = "TXT_OPCION", length = 50)
    public String getTxtOpcion() {
        return txtOpcion;
    }

    public void setTxtOpcion(String txtOpcion) {
        this.txtOpcion = txtOpcion;
    }

    @Column(name = "FLG_ACTIVO")
    public String getFlgActivo() {
        return flgActivo;
    }

    public void setFlgActivo(String flgActivo) {
        this.flgActivo = flgActivo;
    }

    @Column(name = "FEC_CADUCIDAD")
    @Temporal(TemporalType.TIMESTAMP)
    public Date getFecCaducidad() {
        return fecCaducidad;
    }

    public void setFecCaducidad(Date fecCaducidad) {
        this.fecCaducidad = fecCaducidad;
    }

    @Column(name = "NUM_ORDEN")
    public BigInteger getNumOrden() {
        return numOrden;
    }

    public void setNumOrden(BigInteger numOrden) {
        this.numOrden = numOrden;
    }

    @Column(name = "TXT_URL", length = 250)
    public String getTxtUrl() {
        return txtUrl;
    }

    public void setTxtUrl(String txtUrl) {
        this.txtUrl = txtUrl;
    }
    
    @Column(name = "TXT_NOMBRE_OBJETO", length = 250)
    public String getTxtNombreObjeto() {
        return txtNombreObjeto;
    }

    public void setTxtNombreObjeto(String txtNombreObjeto) {
        this.txtNombreObjeto = txtNombreObjeto;
    }

    @Column(name = "FLG_VISIBLE")
    public String getFlgVisible() {
        return flgVisible;
    }

    public void setFlgVisible(String flgVisible) {
        this.flgVisible = flgVisible;
    }
    
    @Column(name = "TXT_OBSERVACION", length = 250)
    public String getTxtObservacion() {
        return txtObservacion;
    }

    public void setTxtObservacion(String txtObservacion) {
        this.txtObservacion = txtObservacion;
    }

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "opcion")
    public List<PerfilOpcion> getPerfilOpcionList() {
        return perfilOpcionList;
    }

    public void setPerfilOpcionList(List<PerfilOpcion> perfilOpcionList) {
        this.perfilOpcionList = perfilOpcionList;
    }

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "nidOpcion")
    public List<Accion> getAccionList() {
        return accionList;
    }

    public void setAccionList(List<Accion> accionList) {
        this.accionList = accionList;
    }

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "nidOpcionPadre")
    public List<Opcion> getOpcionList() {
        return opcionList;
    }

    public void setOpcionList(List<Opcion> opcionList) {
        this.opcionList = opcionList;
    }

    @JoinColumn(name = "NID_OPCION_PADRE", referencedColumnName = "NID_OPCION")
    @ManyToOne
    public Opcion getNidOpcionPadre() {
        return nidOpcionPadre;
    }

    public void setNidOpcionPadre(Opcion nidOpcionPadre) {
        this.nidOpcionPadre = nidOpcionPadre;
    }

    @JoinColumn(name = "NID_MODULO", referencedColumnName = "NID_MODULO", nullable = false)
    @ManyToOne(optional = false)
    public Modulo getNidModulo() {
        return nidModulo;
    }

    public void setNidModulo(Modulo nidModulo) {
        this.nidModulo = nidModulo;
    }

    @Transient
    public String getRuta() {
        return ruta;
    }

    public void setRuta(String ruta) {
        this.ruta = ruta;
    }

    @Transient
    public boolean isBflgActivo() {
        return BflgActivo;
    }

    public void setBflgActivo(boolean BflgActivo) {
        this.BflgActivo = BflgActivo;
    }

    @Transient
    public boolean isBflgConsulta() {
        return BflgConsulta;
    }

    public void setBflgConsulta(boolean BflgConsulta) {
        this.BflgConsulta = BflgConsulta;
    }

    @Override
    public int hashCode() {
        int hash = 0;
        hash += (getId() != null ? getId().hashCode() : 0);
        return hash;
    }


    @Override
    public boolean equals(Object object) {
        // TODO: Warning - this method won't work in the case the id fields are not set
        if (!(object instanceof Opcion)) {
            return false;
        }
        Opcion other = (Opcion) object;
        if ((this.getId() == null && other.getId() != null) || (this.getId() != null && !this.getId().equals(other.getId()))) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return getTxtOpcion();
    }
}
